import { Injectable } from '@angular/core';
import { Graph, ToolsView, EdgeView, Point } from '@antv/x6';

export interface EditableCellToolOptions extends ToolsView.ToolItem.Options {
  x: number;
  y: number;
}

class EditableCellTool extends ToolsView.ToolItem<EdgeView, EditableCellToolOptions> {
  private editorContent!: HTMLInputElement;

  render() {
    super.render();
    const cell = this.cell;
    let x = 0;
    let y = 0;
    let width = 0;
    let height = 0;

    if (cell.isNode()) {
      const position = cell.position();
      const size = cell.size();
      const pos = this.graph.localToGraph(position);
      const zoom = this.graph.zoom();
      x = pos.x;
      y = pos.y;
      width = size.width * zoom;
      height = size.height * zoom;
    } else {
      x = this.options.x - 40;
      y = this.options.y - 20;
      width = 80;
      height = 40;
    }

    const editorParent = ToolsView.createElement('div', false) as HTMLDivElement;
    editorParent.style.position = 'absolute';
    editorParent.style.left = `${x + 40}px`;
    editorParent.style.top = `${y}px`;
    editorParent.style.width = `${width}px`;
    editorParent.style.height = `${height}px`;
    editorParent.style.display = 'flex';
    editorParent.style.alignItems = 'center';
    editorParent.style.textAlign = 'center';

    this.editorContent = ToolsView.createElement('input', false) as HTMLDivElement as HTMLInputElement;
    // this.editorContent.contentEditable = 'true';
    this.editorContent.style.width = '70%';
    // this.editorContent.style.outline = 'none';
    this.editorContent.style.backgroundColor = cell.isEdge() ? '#fff' : '';
    // this.editorContent.style.border = cell.isEdge() ? '1px solid #ccc' : 'none';
    editorParent.appendChild(this.editorContent);
    this.container.appendChild(editorParent);

    this.init();

    return this;
  }

  init = () => {
    const cell = this.cell;
    if (cell.isNode()) {
      const value = cell.attr('text/text') as string;
      if (value) {
        this.editorContent.value = value;
        cell.attr('text/style/display', 'none');
      }
    }
    setTimeout(() => {
      this.editorContent.focus();
    });
    document.addEventListener('mousedown', this.onMouseDown);
    this.editorContent.addEventListener('keydown', this.keydown);
  };


  setValue() {
    const cell = this.cell;
    const value = this.editorContent.value;
    cell.removeTool('editableCell');
    if (cell.isNode()) {
      cell.attr('text/text', value);
      cell.attr('text/style/display', '');
    }
  }

  keydown = (e: KeyboardEvent) => {
    if (e.key === 'Enter') {
      this.setValue();
      this.editorContent.removeEventListener('keyup', this.keydown);
    }
  };

  onMouseDown = (e: MouseEvent) => {
    if (e.target !== this.editorContent) {
      this.setValue();
      document.removeEventListener('mousedown', this.onMouseDown);
    }
  };

  getDistance() {
    const cell = this.cell;
    if (cell.isEdge()) {
      const targetPoint = cell.getTargetPoint();
      const cross = cell.getSourceNode()!.getBBox().intersectsWithLineFromCenterToPoint(targetPoint)!;
      const p = new Point(this.options.x, this.options.y);
      return p.distance(cross);
    }
    return 0;
  }
}

EditableCellTool.config({
  tagName: 'div',
  isSVGElement: false,
});

Graph.registerNodeTool('editableCell', EditableCellTool, true);
